/*
 * @Date: 2022-04-18 00:12:12
 * @LastEditTime: 2022-05-10 10:42:12
 * @brief: 封装Message类操作
 */
#ifndef CHAT_MESSAGE_HPP
#define CHAT_MESSAGE_HPP
#define MAX_BODY_LENGTH 128

#include "messageStruct.h"

#include <iostream>
#include <cassert>
#include <cstring>
#include <cstdlib>

const int max_message_length = MAX_BODY_LENGTH + sizeof(Header);

class Message {
  public:

    enum { header_length = sizeof(Header) };

    // 返回整个包
    const char* data() const {
      return data_;
    }

    char* data() {
      return data_;
    }

    // 返回 body 信息的头地址
    const char* body() const {
      return data_ + header_length;
    }
    char* body() {
      return data_ + header_length;
    }

    std::size_t body_length() const {
      return head_.bodySize;
    }

    // 返回 Message 的头部信息
    Header head() const {
      return head_;
    }

    // 设置 Message 内容
    void setMessage(MessageType type, char *source, char *destination, const void* buffer, std::size_t bufferSize, StatusType stat = NOSTATUS) {
      assert(bufferSize <= MAX_BODY_LENGTH);
      std::memset(data(), 0, sizeof(data_));
      head_.bodySize = bufferSize;
      head_.type = type;
      head_.status = stat;
      std::memcpy(head_.source, source, MAX_USERNAME_LENGTH);
      std::memcpy(head_.destination, destination, MAX_USERNAME_LENGTH);
      std::memcpy(body(), buffer, bufferSize);
      std::memcpy(data(), &head_, header_length);
      // print_header();
    }

    void transfrom(char *source, char *destination, StatusType stat = NOSTATUS) {
      head_.status = stat;
      std::memcpy(head_.source, source, MAX_USERNAME_LENGTH);
      std::memcpy(head_.destination, destination, MAX_USERNAME_LENGTH);
      std::memcpy(data(), &head_, header_length);
    }

    // void print_mes() {
    //   print_header();
    //   std::cout << "\nBody: " << body() << std::endl;
    // }

    void set_data(const void * buffer) {
      std::memcpy(data(), buffer, max_message_length);
      decode_header();
      // print_header();
    }

    // 解析 data 取出 head 信息
    bool decode_header() {
      std::memcpy(&head_, data(), header_length);
      if(head_.bodySize > MAX_BODY_LENGTH) {
        std::cout << "body size " << head_.bodySize << " is too long!!"
        << "type is " << head_.type << std::endl;
        return false;
      }
      return true;
    }

    void print_header() {
      std::cout << "\nbody size :" << head_.bodySize
        << "\ntype is " << head_.type
        << "\nsource is " << head_.source
        << "\ndestination is " << head_.destination
        << "\nstatus is " << head_.status
        << std::endl;
      return;
    }
    

  private:
    Header head_; // 解包出来的头信息
    char data_[header_length + MAX_BODY_LENGTH]; // 实际传递的包(包括header 和 body)
};

#endif // CHAT_MESSAGE_HPP